<?php

namespace app\common\lib;

/**
 * 文字生成图片
 * Class TextToImage
 * @package app\common\lib
 */
class TextToImage
{
    private $width;
    private $fontSize;
    private $fontFile;
    private $image;
    private $lineHeight; // 自定义行高
    private $padding = ['top' => 0, 'right' => 256, 'bottom' => 0, 'left' => 256]; // 默认边距
    private $shadow = ['enabled' => false, 'color' => [0, 0, 0, 50], 'offsetX' => 0, 'offsetY' => 4]; // 默认阴影参数
    private $fontColor = [255, 255, 255, 0]; // 默认字体颜色 (黑色, 不透明)
    private $maxHeight; // 每张图片的最大高度
    private $outPutPath; // 图片输出路径

    public function __construct($width = 1080, $maxHeight = 1920, $fontSize = 57, $lineHeight = 1.2, $fontFile = "", $outPutPath = "")
    {
        $this->width = $width;
        $this->fontSize = $fontSize;
        $this->maxHeight = $maxHeight;
        $this->lineHeight = $lineHeight; // 默认行高倍数
        $this->outPutPath = $outPutPath; // 输出文件夹

        // 如果没有传递字体文件，使用系统默认字体
        if ($fontFile === "") {
            $this->fontFile = $this->getSystemDefaultFont();
        } else {
            $this->fontFile = $fontFile;
        }
    }


    // 获取系统默认字体
    private function getSystemDefaultFont()
    {
        if (PHP_OS_FAMILY === 'Windows') {
            return 'C:/Windows/Fonts/arial.ttf';
        } elseif (PHP_OS_FAMILY === 'Linux') {
            return '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf';
        } elseif (PHP_OS_FAMILY === 'Darwin') { // macOS
            return '/Library/Fonts/Arial.ttf';
        }

        throw new \Exception("无法找到系统默认字体，请手动指定字体文件。");
    }

    // 自动换行
    private function wrapText($text, $maxWidth)
    {
        $textData = array_filter(preg_split("/\r\n|\r|\n/", $text));
        $lines = [];
        foreach ($textData as $row) {
            $words = explode(' ', $row);
            $line = '';
            foreach ($words as $word) {
                $testLine = $line ? $line . ' ' . $word : $word;
                $box = imagettfbbox($this->fontSize, 0, $this->fontFile, $testLine);
                $lineWidth = $box[2] - $box[0];
                if ($lineWidth > $maxWidth) {
                    $lines[] = $line;
                    $line = $word;
                } else {
                    $line = $testLine;
                }
            }
            $lines[] = $line;
            $lines[] = " ";
        }

        return $lines; // 返回每一行文本
    }

    // 设置边距（可单独设置四个方向的边距）
    public function setPadding($top, $right, $bottom, $left)
    {
        $this->padding = [
            'top' => $top,
            'right' => $right,
            'bottom' => $bottom,
            'left' => $left
        ];
    }

    // 设置阴影
    public function setShadow($enabled, $color = [0, 0, 0, 50], $offsetX = 2, $offsetY = 2)
    {
        $this->shadow = [
            'enabled' => $enabled,
            'color' => $color,
            'offsetX' => $offsetX,
            'offsetY' => $offsetY
        ];
    }

    // 设置字体颜色和透明度
    public function setFontColor($r, $g, $b, $alpha = 0)
    {
        $this->fontColor = [$r, $g, $b, $alpha];
    }

    // 设置行高倍数
    public function setLineHeight($lineHeight)
    {
        $this->lineHeight = $lineHeight;
    }

    // 根据文本生成图片（递归生成多张图片）
    public function setText($text)
    {
        // 自动换行并计算行数
        $lines = $this->wrapText($text, $this->width - $this->padding['left'] - $this->padding['right']);
        // 行高
        $lineHeight = $this->fontSize * $this->lineHeight;

        // 计算每张图片能容纳的行数
        $maxLinesPerImage = floor(($this->maxHeight - $this->padding['top'] - $this->padding['bottom']) / $lineHeight);

        // 递归生成图片
        return $this->createImagesFromText($lines, $maxLinesPerImage);
    }

    // 递归生成图片
    private function createImagesFromText($lines, $maxLinesPerImage, $imageIndex = 1, $img = [])
    {
        if (!is_dir($this->outPutPath)) {
            mkdir($this->outPutPath, 0755, true);
        }

        $filename = $this->outPutPath . "output_image_$imageIndex.png";
        $img[] = $filename;
        // 如果剩余的行数少于或等于能容纳的行数
        if (count($lines) <= $maxLinesPerImage) {
            $this->generateImage($lines, $this->maxHeight, $filename);
        } else {
            // 取出能放入当前图片的行数
            $currentLines = array_slice($lines, 0, $maxLinesPerImage);
            $remainingLines = array_slice($lines, $maxLinesPerImage);
            // 生成当前图片
            $this->generateImage($currentLines, $this->maxHeight, $filename);

            // 递归生成下一张图片
            $img = $this->createImagesFromText($remainingLines, $maxLinesPerImage, $imageIndex + 1, $img);
        }

        return $img;
    }

    // 生成图片
    private function generateImage($lines, $height, $outputPath)
    {
        // 创建图片
        $this->image = imagecreatetruecolor($this->width, $height);
        imagesavealpha($this->image, true);

        // 透明背景
        $transparent = imagecolorallocatealpha($this->image, 0, 0, 0, 127);
        imagefill($this->image, 0, 0, $transparent);

        // 字体颜色
        $fontColor = imagecolorallocatealpha(
            $this->image,
            $this->fontColor[0],
            $this->fontColor[1],
            $this->fontColor[2],
            $this->fontColor[3]
        );

        // 行高
        $lineHeight = $this->fontSize * $this->lineHeight;

        // 开始绘制文本
        $y = $this->padding['top'] + $this->fontSize;

        foreach ($lines as $line) {
            $box = imagettfbbox($this->fontSize, 0, $this->fontFile, $line);
            $textWidth = $box[2] - $box[0];

            $x = ($this->width - $textWidth) / 2;

            // 绘制阴影（如果启用）
            if ($this->shadow['enabled']) {
                $shadowColor = imagecolorallocatealpha(
                    $this->image,
                    $this->shadow['color'][0],
                    $this->shadow['color'][1],
                    $this->shadow['color'][2],
                    $this->shadow['color'][3]
                );
                imagettftext($this->image, $this->fontSize, 0, $x + $this->shadow['offsetX'], $y + $this->shadow['offsetY'], $shadowColor, $this->fontFile, $line);
            }

            // 绘制文本
            imagettftext($this->image, $this->fontSize, 0, $x, $y, $fontColor, $this->fontFile, $line);
            $y += $lineHeight;
        }

        // 保存图片
        imagepng($this->image, $outputPath);

        // 释放内存
        imagedestroy($this->image);
    }
}